
package xaj.scc.ast;

import java.util.List;

import xaj.scc.util.mapping.AddGrammar;
import xaj.scc.util.mapping.Mapping;
import xaj.scc.util.mapping.errorMapping;
import polyglot.ast.Node;
import polyglot.ast.Term;
import polyglot.ext.jl.ast.Term_c;
import polyglot.types.SemanticException;
import polyglot.util.Position;
import polyglot.visit.CFGBuilder;
import polyglot.visit.TypeChecker;



public class GrammarNodeOld_c extends Term_c implements GrammarNodeOld {

	private List<Production> production;
	private String name;
	private boolean isoverrides;
	static Mapping mapeamento;
	static errorMapping erro;
	static AddGrammar grammar;
	
	
	public GrammarNodeOld_c(String name, List<Production> production, Position pos) {
		super(pos);
		this.name = name;
		this.production = production;
		isoverrides = false;
	}
	
	public GrammarNodeOld_c(String name, Position pos) {
		super(pos);
		this.name = name;
		this.production = null;
		isoverrides = true;
	}

	public List<Production> getProductions() {
		return production;
	}

	public String getExtends() {
		return name;
	}

	public boolean isOverrides() {
		return isoverrides;
	}

	public String toString() {
		String grammar;
		if(isOverrides()) {
			grammar = "@Grammar overrides " + getExtends() +";";
		} else {
			grammar = "@Grammar extends " + getExtends() + "{\n";
			String s;
			for(Production p : production ) {
				s = "\t" + p.toString() + "\n";
				grammar += s;
			}
			grammar += "}";
		}
		return grammar;
	}
	
	@Override
	public List acceptCFG(CFGBuilder arg0, List arg1) {
		//Comentário da interface polyglot.ast.Term
		/**
	     * Visit this node, calling v.edge() for each successor in succs,
	     * if data flows on that edge.
	     */
		return arg1;
	}

	@Override
	public Term entry() {
		//Comentário da interface polyglot.ast.Term
		/**
	     * Return the first (sub)term performed when evaluating this
	     * term.
	     */
		return this;
	}
	
	//Esses são os métodos que eu devo implementar para fazer a análise semântica
	// do @Grammar
	
	/*public NodeVisitor typeCheckEnter(TypeChecker tc) throws SemanticException {		
		return tc;
	}*/
	
	public Node typeCheck(TypeChecker tc) throws SemanticException {
		System.out.println("Começando a fazer a análise semântica do nó");
		
		
		grammar =  AddGrammar.getInstance();
		mapeamento = Mapping.getInstance();
		erro = errorMapping.getInstance();
		
		mapeamento.mappingTerm();
		
		//int index = abc.main.Main.v().soot_args.indexOf("-sourceroots");
		
		//for(int i=0;i< abc.main.Main.v().soot_args.size();i++)
		//	System.out.println( abc.main.Main.v().soot_args.get(i));
			
		
		//System.out.println("\n\n\n\n\n");
		
		
		//for(int i=0;i< abc.main.Main.v().polyglot_args.size();i++)
		//	System.out.println(abc.main.Main.v().polyglot_args.get(i).toString() + i);
		
		
		//-----------------classes imports------------------------
		for(Object e: abc.main.Main.v().aspect_sources){
			String imp = e.toString();
			String aux[];
			aux = imp.split("\\u005C");
			imp = aux[aux.length-1];
			grammar.insertClassesImports(imp);
			
		}
		
		
		
		
		
		
		
		
		// ----- new non-terminals ------------------------\";
		
		for( int i=0;i<production.size();i++){
			
			
			if(!mapeamento.nonTerms.containsKey(name))
				erro.sentError(getExtends(),production.get(i).getLeftSide());
			
			grammar.insertNonTerminal("non terminal "+ mapeamento.nonTerms.get(name) 
					+ " " + production.get(i).getLeftSide()+";\n\n");
			
			//Adicionado por Leonardo
			grammar.addNonTerminal(production.get(i).getLeftSide());
		}
		
		// ---- Productions -------------------------------\n"+
			 
		//percorrendo  a lista de produ��es e imprimindo
		//Espero que esse teste seja sempre verdadeiro (Confirmar isso para elimina-lo)
		if(production.size() > 0);
			grammar.insertProductions( "extend " + name + " ::= " +
					production.get(0).getLeftSide() + ":rt {: RESULT = rt; :};\n\n");
		for( int i=0;i<production.size();i++){
			grammar.insertProductions(production.get(i).toString()+"\n");
			
		}
		
		
		
		
		
		//if(!mapeamento.terms.isEmpty()){System.out.println("Mapeado com sucesso \n\n");}
		
		//System.out.println(production.get(1));
		
		/*
		//Gambiarra para fazer funcionar
		//Deve ser feito uma análise semântica neste nó e depois ele deve gerar
		//arquivos de extensão .ppg, e em seguida ele deve ser apagado da AST
		
		//Lista vazia. Classe com corpo vazio
		List l = new TypedList(new LinkedList(), ClassMember.class, false);
		ClassBody classbody = new ClassBody_c(position(), l);
		//Classe não implementa nenhuma interface
		List inter = new TypedList(new LinkedList(),TypeNode.class, false);
		
		
		
		ClassDecl classdecl = new ClassDecl_c(position(), Flags.PRIVATE, "SemNome", 
				null, inter, classbody);
		return classdecl;*/
		return this;
	

	}

	@Override
	public void accept(Visitor v) {
		v.visitGrammarNodeOld(this);
		
	}
	
}
